/**      
 * @file			cstring_getline.cpp
 * @description		This program reads a file specified by the user
 *					and determines the longest line, the line number
 *					of the longest line, and the total lines in the
 *					file. Then it outputs that data to the user.
 * @course			CSCI 123 Section 00000
 * @assignment		
 * @date			3/7/2006
 * @author			Brad Rippe (00000000) brippe@fullcoll.edu
 * @version			1.0
 */
#include <iostream>		// cin and cout
#include <fstream>		// file input and output
#include <cstdlib>		// exit() 
#include <cstring>		// strncpy()
using namespace std;

/**
 * Application Constants
 */
const int LINE_SIZE = 300;
const int NAME_SIZE = 80;

/**
 * Prompts the user for a file name and gets the file name
 * from the user.
 * @param	aFileName the name of the file to be set
 * @pre		aFileName must be initialized
 * @post	aFileName has a cstring of 80 characters that provides
 *			the name of a file
 */
void getFileName(char aFileName[]);

/**
 * Opens an input file to prepare it for reading, if the file was unable
 * to be opened, a message will be sent to standard output and the program
 * will be terminated
 * @param	aInFile		the name of the input file stream to be opened
 * @param	aFileName	the name of the file to open
 * @pre		input file stream has been initialized and aFileName has been
 *			defined
 * @post	the input file stream has been opened
 */
void openFile(ifstream& aInFile, const char aFileName[]);

/**
 * Sends 79 asterisks to standard output for presentation
 * @pre		none
 * @post	79 asterisks were sent to standard output
 */
void outputAsterisks();

/**
 * Analyzes lines of text from the input file stream, determines which is the 
 * longest line of text, the longest line's line number (in the file), the length
 * of the longest line, and the total number of lines in the file.
 * @param	aInFile the file input stream to retrieve lines from
 * @param	aNumberOfLines the total number of lines in the file
 * @param	aMaxLineLength the length of the longest line
 * @param	aLongestLineNumber the line number of the longest line
 * @param	aLongestLine the text of the longest line
 */
void analyzeLines(ifstream& aInFile, int& aNumberOfLines, 
				  int& aMaxLineLength, int& aLongestLineNumber, 
				  char aLongestLine[]);
/**
 * @return zero if the application executes successfully
 */
int main() {
	int	numberOfLines		= 0;
	int	maxLineLength		= 0;
	int longestLineNumber	= 0;	
	char longestLine[LINE_SIZE];
	char fileName[NAME_SIZE];
	ifstream inFile;

	getFileName(fileName);
	
	openFile(inFile, fileName);	
	analyzeLines(inFile, numberOfLines, maxLineLength, 
				 longestLineNumber, longestLine);	
	outputAsterisks();
	inFile.close();
	
	cout << "There are " << numberOfLines << " lines in the file.\n";
	cout << "The longest line, line number " << longestLineNumber;
	cout << ", is " << maxLineLength << " characters long\n";
	outputAsterisks();
	cout << "The line is:\n" << longestLine << endl;
	outputAsterisks();
	return 0;
}

void getFileName(char aFileName[]) {
	cout << "Please type the name of your input file.\n";
	cin >> aFileName;
}

void openFile(ifstream& aInFile, const char aFileName[]) {
	aInFile.open(aFileName);
	if(aInFile.fail()) {
		cout << "Couldn't open " << aFileName << " for input.\n";
		exit(1);
	}
}

void outputAsterisks() {
	for(int i = 0; i < 79; i++)
		cout << '*';
	cout << endl;
}

void analyzeLines(ifstream& aInFile, int& aNumberOfLines, 
				  int& aMaxLineLength, int& aLongestLineNumber, 
				  char aLongestLine[]) {
    
	int lineLength = 0;
	char line[LINE_SIZE];

	// Find the longest line
	while(true) {
		aInFile.getline(line, LINE_SIZE);		
		if(aInFile.eof()) 
			break;
		lineLength = aInFile.gcount();
		// or you could use strlen(line); from cstring library
		// there is more than one way to skin a cat in C++
		aNumberOfLines++;

		if(lineLength > aMaxLineLength) {
			aLongestLineNumber = aNumberOfLines;
			aMaxLineLength = lineLength;
			strncpy(aLongestLine, line, LINE_SIZE);
			//strcpy_s(aLongestLine, LINE_SIZE, line);	
			// copies a cstring from aLine to aLongestLine
			// strcpy_s() removes the deprecation warning in VS2005
		}		
	}
}
